#include "StdAfx.h"
#include "PhotoProject.h"


CPhotoProject::CPhotoProject(void)
{
	m_isEdited = false;
	m_throw = false;
	m_fileName = NULL;
}
void CPhotoProject::CreateBackup()
{
	m_backUp.m_image.CopyOf(m_image);
	m_backUp.m_previousImage.CopyOf(m_previousImage);
	m_backUp.m_isEdited= m_isEdited;
	m_backUp.m_previousEditState= m_previousEditState;
};
void CPhotoProject::RetoreBackup(bool full)
{
	m_image.CopyOf(m_backUp.m_image);
	if(full)
	{
		m_previousImage.CopyOf(m_backUp.m_previousImage);
		m_isEdited= m_backUp.m_isEdited;
		m_previousEditState= m_backUp.m_previousEditState;
	}
};
void CPhotoProject::Open(char* fileName)
{
	m_isEdited = false;
	m_fileName = new char[strlen(fileName)];
	strcpy_s(m_fileName,strlen(fileName)+1,fileName);
	IplImage* pImage =  cvLoadImage(fileName);
	if(pImage!= NULL)
	{
		m_image.CopyOf(pImage);
		cvReleaseImage(&pImage);
	}
	m_previousImage.CopyOf(m_image);
	m_backUp.Clear();
}
void CPhotoProject::Save(char* fileName)
{
	m_fileName = new char[strlen(fileName)];
	strcpy_s(m_fileName,strlen(fileName)+1,fileName);
	Save();
}
void CPhotoProject::Save()
{
	m_isEdited = false;
	m_image.Save(m_fileName);
}
int CPhotoProject::GetHeight()
{
	return m_image.Height();
}
int CPhotoProject::GetWidth()
{
	return m_image.Width();
}

void CPhotoProject::DrawImage(CStatic &pC,bool fitScreen)
{
	HDC hDC = pC.GetDC()->GetSafeHdc();
	CRect rect,dr;
	pC.GetClientRect(rect);	
	int w = m_image.Width();
	int h = m_image.Height();
	float sX = (float)rect.right/w;
	float sY = (float)rect.bottom/h;
	int m = 10;
	int mx,my;
	if(w<rect.right-2*m && h < rect.bottom-2*m && !fitScreen)
	{
		mx=(rect.right-w)/2+m;
		my=(rect.bottom-h)/2+m;
	}
	else if(sX<sY)
	{
		my=(int)(rect.bottom-h*sX)/2+m;
		mx = m;
	}
	else
	{
		mx=(int)(rect.right-w*sY)/2+m;
		my=m;
	}
	dr.left = mx;
	dr.right = rect.right-mx;
	dr.top = my;
	dr.bottom = rect.bottom-my;
	m_image.DrawToHDC(hDC,&dr);
}
void CPhotoProject::Undo()
{
	m_isEdited = m_previousEditState;
	m_image.CopyOf(m_previousImage);
}
void CPhotoProject::Edited()
{
	
	if(!m_throw)
	{
		m_previousEditState = m_isEdited;
		m_previousImage.CopyOf(m_image);
	}
	m_isEdited = true;

}
void CPhotoProject::BeginComplex()
{
	m_previousEditState = m_isEdited;
	m_previousImage.CopyOf(m_image);
	m_throw = true;
}
void CPhotoProject::EndComplex()
{
	m_throw = false;
}
void CPhotoProject::Resize(int w,int h)
{
	Edited();
	Mat im(m_image.GetImage());
	Mat im_out;
  
	resize(im,im_out,Size(w,h),0,0,INTER_LINEAR);
	IplImage newImg = im_out;
	m_image.CopyOf(&newImg);
}
void CPhotoProject::Flip(int axis)
{
	Edited();
	cvFlip(m_image.GetImage(),m_image.GetImage(),axis);
}
void CPhotoProject::Transpose()
{
	Edited();
	IplImage* newImg = cvCreateImage(
		cvSize(m_image.Height(),m_image.Width()),
		m_image.GetImage()->depth,m_image.GetImage()->nChannels);

	cvTranspose(m_image.GetImage(),newImg);
	m_image.CopyOf(newImg);
	cvReleaseImage(&newImg);
}
void CPhotoProject::Blur(int n)
{
	Edited();
	blur((_InputArray)m_image.GetImage(),(_OutputArray)m_image.GetImage(),cvSize(n,n));
}
void CPhotoProject::MedianFilter(int n)
{
	Edited();
	
	medianBlur((_InputArray)m_image.GetImage(),(_OutputArray)m_image.GetImage(),n);
}
void CPhotoProject::EdgeDetect(int threshold)
{
	Edited();
	Mat im_out;
	Canny((_InputArray)m_image.GetImage(),im_out,threshold/3,threshold,3);
	IplImage newImg = im_out;
	m_image.CopyOf(&newImg);
}
void CPhotoProject::AdjustBrightness(int b)
{
	Edited();
	cvAddS(m_image.GetImage(), cvScalar(b,b,b), m_image.GetImage());
}
void CPhotoProject::AdjustContrast(double c,double shift)
{
	Edited();
	cvConvertScale(m_image.GetImage(), m_image.GetImage(), c,shift);
	//cvScale(m_image.GetImage(), m_image.GetImage(), c);
}

void CPhotoProject::Grayscale()
{
	Edited();
	if(m_image.GetImage()->nChannels == 1)
	{
		return;
	}
	Mat im_out;
	cvtColor((_InputArray)m_image.GetImage(),im_out, CV_BGR2GRAY,1);
	IplImage newImg = im_out;
	m_image.CopyOf(&newImg);
}
void CPhotoProject::Invert()
{
	Edited();
	cvNot(m_image.GetImage(), m_image.GetImage());
}
void CPhotoProject::Eroding()
{
	Edited();
	Mat im_out;
	erode((_InputArray)m_image.GetImage(),im_out,cv::Mat());
	IplImage newImg = im_out;
	m_image.CopyOf(&newImg);
	
}
void CPhotoProject::Dilating()
{
	Edited();
	Mat im_out;
	dilate((_InputArray)m_image.GetImage(),im_out,cv::Mat());
	IplImage newImg = im_out;
	m_image.CopyOf(&newImg);
}
CPhotoProject::~CPhotoProject(void)
{
	if(m_fileName != NULL)
	{
//		delete []m_fileName;
	}
}
